<template lang="pug">
  el-form(
    ref="form"
    :size="size"
    :model="form"
    :disabled="disabled"
    :label-position="labelPosition"
    :label-width="isFilter ? 'auto' : labelWidth"
    )
    slot(name="front")
    el-row(:gutter="16")
      el-col(
        v-for="(item, index) in effectItems"
        :key="item.key"
        :class="{'lastRow': isFilter && lastRow(index)}"
        v-bind="item.layoutCol || layoutCol"
      )
        el-form-item(:label="item.label" :rules="item.rules || []" v-if="!item.hidden && item.slot")
          slot(:name="item.key")
        form-item(
          v-else
          :fitem="{...item, initialValue: form[item.key]}"
          :disabled="disabled"
          v-model="form[item.key]"
          @changeHandle="formvalueChange"
        )
      slot(name="otherItems")
      el-col(:span="isFilter ? filterBtnSpan : 24" :class="{[btnClass]: !!btnClass, 'tr': !btnClass}" v-if="showBtns")
        el-button(:size="size" @click="filterUnfolder = !filterUnfolder" href="javascript:" class="f12" v-if="showFolder && isFilter && (effectTotalItems.length > 24 / _col)")
          | {{ filterUnfolder ? '收起' : '展开' }}
          i(:class="filterUnfolder ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" class="ml5")
        el-button(:size="size" v-if="reset || isFilter" :loading="submitting" :disabled="sureDisabled" @click="resetForm") 重置
        el-button(:size="size" v-if="!isFilter" @click="cancelHandle") {{cancelText}}
        el-button(:size="size" type="primary" @click="submitForm" :loading="submitting") {{isFilter ? '查询' : (sureText || '保存')}}
</template>
<script>
import FormItem from './FormItem'
import dayjs from 'dayjs'

const layoutCol = {
  sm: 12,
  md: 8,
  lg: 6
}

export default {
  name: 'FormBox',
  components: {
    FormItem
  },
  props: {
    size: {
      type: String,
      default: 'small'
    },
    labelPosition: {
      type: String,
      default: ''
    },
    btnClass: {
      type: String,
      default: ''
    },
    labelWidth: {
      type: String,
      default: '100px'
    },
    // 是否是表格搜索表单
    isFilter: {
      type: Boolean,
      default: false
    },
    showBtns: {
      type: Boolean,
      default: true
    },
    // 是否显示重置按钮
    reset: {
      type: Boolean,
      default: false
    },
    // 是否显示取消按钮， 主要用于弹窗表单
    cancel: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    cancelText: {
      type: String,
      default: '返回'
    },
    // 确认按钮文字
    sureText: {
      type: String,
      default: '保存'
    },
    // 表格搜索表单缩进显示条目数
    showFolder: {
      type: Boolean,
      default: true
    },
    layoutCol: {
      type: Object,
      default: () => {
        return layoutCol
      }
    },
    // 对外暴露submitting属性，用于显示提交按钮的loading状态
    submitting: {
      type: Boolean,
      default: false
    },
    items: {
      type: Array,
      default: () => []
    },
    layout: {
      type: String,
      default: 'horizontal'
    },
    searchHandle: {
      type: Function,
      default: null
    },
    submitHandle: {
      type: Function,
      default: null
    }
  },
  computed: {
    _col () {
      const { layoutCol } = this
      const _width = document.documentElement.clientWidth
      const _col = _width > 1200 ? 'lg' : _width > 992 ? 'md' : 'sm'
      return layoutCol[_col]
    },
    effectTotalItems () {
      const { items } = this
      return items.filter((item) => {
        return !item.hidden
      })
    },
    // 计算显示的表单项
    effectItems () {
      const { items, isFilter, filterUnfolder } = this
      const VItems = items.filter((item) => {
        return !item.hidden
      })
      if (isFilter && !filterUnfolder) {
        return VItems.filter((item, index) => {
          return index < (24 / this._col)
        })
      }
      return VItems
    }
  },
  data () {
    return {
      form: {},
      initialForm: null,
      rules: {},
      filterUnfolder: false,
      sureDisabled: false,
      filterBtnSpan: 6
    }
  },
  watch: {
    effectItems: {
      handler (val) {
        const form = {}
        const rules = {}
        this.filterBtnSpan = 24 - val.length % (24 / this._col) * this._col
        val.forEach(item => {
          // 获取校验规则
          if (item.rule) {
            rules[item.key] = item.rule
          }
          // 获取初始值
          if (item.value != null) {
            form[item.key] = item.value
          } else if (item.initialValue != null) {
            form[item.key] = item.initialValue
          } else if (item.type && !item.slot) {
            if ((item.type.includes('range') || item.type === 'upload' || item.type === 'upload' || item.mutiple)) {
              form[item.key] = this.form[item.key] || []
            } else {
              switch (item.type) {
                case 'checkbox': case 'cascader': case 'transfer':case 'upload':
                  form[item.key] = this.form[item.key] || []
                  break
                case 'switch':
                  form[item.key] = this.form[item.key] || false
                  break
                default:
                  form[item.key] = this.form[item.key] || ''
              }
            }
          } else {
            form[item.key] = this.form[item.key] || ''
          }
        })
        this.form = form
        this.rules = rules
        this.initialForm = !this.initialForm ? { ...form } : this.initialForm
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    lastRow (index) {
      const { _col, effectTotalItems } = this
      const span = 24 / _col
      const totalRows = parseInt(effectTotalItems.length / span)
      const lastRowIndex = effectTotalItems.length % span ? effectTotalItems.length % span : (span - 1)
      return index > (totalRows * span) - 1 && index < (totalRows * span) + lastRowIndex
    },
    // 监听表单各项的值的变化
    formvalueChange ({ value, key }) {
      this.form[key] = value
      this.$emit('formChange', { value, key })
    },
    submitForm (e) {
      const { form, items } = this
      e && e.preventDefault && e.preventDefault()
      const itemsA = items.filter(x => !x.hidden && !x.slot)
      return new Promise(resolve => {
        this.$refs.form.validate(valid => {
          if (valid) {
            const formTemp = {}
            for (const item of itemsA) {
              formTemp[item.key] = form[item.key]
              // 是否时间格式化
              if ((item.formatFlag || this.isFilter) && item.type && (item.type.includes('date') || item.type.includes('time')) && form[item.key]) {
                const formatStr = item.type.includes('time') ? 'YYYY-MM-DD hh:mm:ss' : 'YYYY-MM-DD'
                if (item.type.includes('range')) {
                  if (form[item.key].length > 0) {
                    formTemp['begin' + item.key] = dayjs(new Date(form[item.key][0])).format(formatStr)
                    formTemp['end' + item.key] = dayjs(new Date(form[item.key][1])).format(formatStr)
                  }
                  delete formTemp[item.key]
                } else {
                  formTemp[item.key] = dayjs(new Date(form[item.key])).format(formatStr)
                }
              }
              // 上传文件格式化文件
              if (item.type === 'upload' && form[item.key] && Array.isArray(form[item.key])) {
                formTemp[item.key] = []
                form[item.key].map(file => {
                  if (file.response && file.response.code === 0) {
                    formTemp[item.key].push({
                      url: file.response.data
                    })
                  }
                  if (file.url) {
                    formTemp[item.key].push({
                      url: file.url
                    })
                  }
                })
              }
            }
            // 搜索表单
            if (this.searchHandle) {
              this.searchHandle(formTemp)
            }
            // 提交表单
            if (this.submitHandle) {
              this.submitHandle(formTemp)
            }
            resolve(formTemp)
          } else {
            console.log('error submit!!')
            this.$message.error('请正确输入表单项')
            return false
          }
        })
      })
    },
    // 重置表单
    resetForm () {
      this.form = { ...this.initialForm }
      if (this.searchHandle) {
        this.searchHandle(this.form)
      }
    },
    cancelHandle () {
      this.$refs.form.resetFields()
      this.$refs.form.clearValidate()
      this.$emit('cancelHandle')
    }
  }
}
</script>
<style lang="scss" scoped>
.lastRow{
  /deep/ .el-form-item{
    margin-bottom: 0
  }
}

// .filterBtns{
//   padding-top: 3px;
//   box-sizing: border-box;
// }

.el-col-24 {
  &.filterBtns{
    padding-top: 0
  }
}
</style>
